package ar.edu.unq.tpi.uis.tepe3.wicket.components;

import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.hibernate.Session;
import org.hibernate.Transaction;

import ar.edu.unq.tpi.uis.tepe3.persistencia.HibernateUtil;

@SuppressWarnings("serial")
public abstract class AbstractFormABM<T> extends Form {
	
	private FeedbackPanel feedbackPanel;
	private T object;

	public AbstractFormABM(String id, T object) {
		super(id, new CompoundPropertyModel(object));
		this.feedbackPanel = new FeedbackPanel("feedback");
		this.add(feedbackPanel);
		this.object = object;
		this.addFields();
		this.addButtons();
	}
	
	protected void addButtons() {
		this.add(new Button("enviar") { 
			@Override 
			public void onSubmit() {
				try {
					save();
				} catch (RuntimeException e) {
					feedbackPanel.error(errorMsg());
//					throw e;
					return;
				}
				redirectToListPage();
			} 
        }); 
        this.add(new Link("cancel") {
			@Override
			public void onClick() {
				redirectToListPage();
			}
		});
	}

	protected void save(){
		Session sess = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction tx = null;
		try {
			tx = sess.beginTransaction();
			this.updateObject(sess);
			sess.saveOrUpdate(this.getObject());
			tx.commit();
		} catch (RuntimeException e) {
			if (tx != null)
				tx.rollback();
			throw e;
		} finally{
			if(sess.isOpen()) sess.close();
		}
	}
	
	
	/**
	 * Sobreescribir este metodo si se necesita modificar el objecto antes de persistirlo
	 * 
	 * @param sess
	 */
	protected void updateObject(Session sess) {}

	protected abstract void addFields();
	protected abstract void redirectToListPage();
	
	public FeedbackPanel getFeedbackPanel() {
		return feedbackPanel;
	}

	public void setFeedbackPanel(FeedbackPanel feedbackPanel) {
		this.feedbackPanel = feedbackPanel;
	}

	public T getObject() {
		return object;
	}

	public void setObject(T object) {
		this.object = object;
	}
	
	protected String errorMsg(){
		return "Error en la creacion";
	}

}
